/***************************************************************************

Google Bot Dictionary Bot
Bot Coder - Sun Thurein Aung
Dictionary Source - Mysteryzillion
Version - 2.0
Last Updated - 11.01.2009
GTalk connection code from 
http://jlindberg.blogspot.com/2007/12/simple-echo-bot-in-java-google-talk-now.html
http://wsdlj2ee.blogspot.com/2005/09/writing-xmpp-chat-client-in-java.html

***************************************************************************/



import java.io.*;
import java.util.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.Roster.SubscriptionMode;

public class GTalkDict{
	
	String username;
	String password;
	String dictFile, tempFile, unknownFile;
    String[] from;
    String dictversion, botversion;
	Hashtable dictionary, temp_dict, unknown;
    String[] commands = new String[]{"/help" , "/about", "/total", "/add"};

	
	XMPPConnection conn;
	
	GTalkDict(String configFile) {
		readConfigFile(configFile);	
		loadDictionary();
		startConnection();
	}
	/* ****************************************************************************/
	void startConnection() {
		try {
			ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
			conn = new XMPPConnection(config);
		
			conn.connect();
			conn.login(username, password);
            Presence presenc = new Presence(Presence.Type.available);
            presenc.setStatus("English - Myanmar Dictionary. Type /help for help menu");
			// Become available.
			conn.sendPacket(presenc);
			// Auto-accept all friend requests.   
			conn.getRoster().setSubscriptionMode(SubscriptionMode.accept_all);
		}
		catch(XMPPException e) {
			e.printStackTrace();
		}

/* ****************************************************************************/
		final MessageListener messageListener = new MessageListener() {
			public void processMessage(Chat chat, Message message) {
				
				if ((message.getType() ==  Message.Type.chat
				|| message.getType() == Message.Type.normal)
		         && message.getBody()!= null) {
					try {
                        String[] text;
                        from = message.getFrom().split("/");
						Date date = new Date();		// get current date and time
						DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm ");
						System.out.println( dateFormat.format(date) +  message.getFrom() + " ==> " + message.getBody());  // log the words
                        text = message.getBody().toLowerCase().split(" ");// change the incoming text to lower case characters
                        if (isCommand(text[0]))
                        {
                            doCommand(text, chat);  // if the text is command word, do the command function
                        } // end of isCommand if
                        else if (dictionary.containsKey(text[0])) // if the dictionary has the meaning of the given text
                        {
                                chat.sendMessage((String)dictionary.get(text[0]));
                        }
                        else if (temp_dict.containsKey(text[0]))
                        {
                                chat.sendMessage("Your word is not found in our dictionary. However, one of our users suggested the following meaning.\n" + (String)temp_dict.get(text[0]));
                        }
                        else
                        {
                            if (unknown.containsKey(text[0])==false)
                            {
                            unknown.put(text[0], from[0]);
                            WriteToFile(unknownFile, from[0] + "\t" + text[0] + "\r\n");
                            }
                            chat.sendMessage("Sorry, your word is not in dictionary.");
                        } // end of else
					} catch(XMPPException e) {
						e.printStackTrace();
					}
				}
		     }
		   };
		   
		  conn.getChatManager().addChatListener(
		       new ChatManagerListener() {
		         public void chatCreated(Chat chat, boolean createdLocally) {
		           chat.addMessageListener(messageListener);
		         }
		     }
		    );
		}

/* ****************************************************************************/
	public void readConfigFile(String configFile) {
		try {
			BufferedReader br = new BufferedReader(new FileReader(configFile));
            System.out.println(configFile);
			username = br.readLine();
			password = br.readLine();
			dictFile = br.readLine();
            tempFile = br.readLine();
            unknownFile = br.readLine();
            botversion = br.readLine();
			br.close();
			System.out.println(username);
			System.out.println(password);
			System.out.println(dictFile);
            System.out.println(tempFile);
            System.out.println(unknownFile);
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}	
/******************************************************************************/
	public void loadDictionary() {
		String line;
        String[] token;
		dictionary = new Hashtable();
        temp_dict = new Hashtable();
        unknown = new Hashtable();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(dictFile), "UTF-8"));
            dictversion = br.readLine();
			line = br.readLine();
			
			while(line != null) {
                token = line.split("\\t");
                if (dictionary.containsKey(token[0]))
                {
                     dictionary.put(token[0], dictionary.get(token[0]) + " "  + "(" + token[1] + ")" + " " + token[2]);
                }
                else
                {
                    dictionary.put(token[0], "(" + token[1] + ")" + " " + token[2]);
                }
                
                line = br.readLine();
			}
            br.close();
            
            System.out.println("dictionary loaded.");
		}
		catch(IOException e) {
			e.printStackTrace();
		}// end catch

        // loading temp dictionary
        try {
			BufferedReader temp_br = new BufferedReader(new InputStreamReader(new FileInputStream(tempFile), "UTF-8"));
            line = temp_br.readLine();

			while(line != null) {
                token = line.split("\\t");
                if (temp_dict.containsKey(token[1]))
                {
                     temp_dict.put(token[1], temp_dict.get(token[1]) + " "  + "(" + token[2] + ")" + " " + token[3]);
                }
                else
                {
                    temp_dict.put(token[1], "(" + token[2] + ")" + " " + token[3]);
                }

                line = temp_br.readLine();
			}
            temp_br.close();

            System.out.println("temp dictionary loaded.");
		}
		catch(IOException e) {
			e.printStackTrace();
		}// end catch

        //load the unknown words
           try {
			BufferedReader unknown_br = new BufferedReader(new InputStreamReader(new FileInputStream(unknownFile), "UTF-8"));
            line = unknown_br.readLine();

			while(line != null) {
                token = line.split("\\t");
                unknown.put(token[1], token[0]);
                line = unknown_br.readLine();
			}
            unknown_br.close();

            System.out.println("unknown loaded.");
		}
		catch(IOException e) {
			e.printStackTrace();
		}// end catch

	}
/* ****************************************************************************/
    // write the text to the given file name
    // return true if text are successfully write to file, otherwise return false
    boolean WriteToFile(String filename, String text) // write the text to the given file name
    {
        File file = new File(filename);
        if(!file.exists())
        {
            System.out.println(filename + " not found.");
            return false;
        }
        else
        {
            try
            {
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter
                                 (new FileOutputStream(file,true),"UTF8"));
                out.write(text);
                out.close();
                return true;
            }catch(Exception ue){
                System.out.println(ue);
                return false;
            }
            
        }// end else
    }// end WriteToFile function
/* ****************************************************************************/
    boolean isCommand(String text) // check the given text is command word or not
    {
        for (int i=0; i <commands.length; i++)
        {
            if (commands[i].equals(text))
                return true; // given text is command
        }
        return false; // given text is not command
    }// end of isCommand function
/* ****************************************************************************/
    void doCommand(String[] command, Chat chat)
       /*   0 - /help
            1 - /bout
            2 - /total
            3 - /add   */
    {
        String message="";
        if (commands[0].equals(command[0])) // if command is /help
        {
            message = "To translate a english word, simply type a word and press Enter. Bot will give you the meaning of word in burmese.\nYou need to have Zawgyi font to see in burmese.\n/help - display this menu\n/about - About this dictionary\n/total - total words in dictionary\n/add English Word_Category Burmese - to add new words into dictionary.";

        }// end of if /help

        if (commands[1].equals(command[0])) // if command is /about
        {
            message = dictversion + "\n" + botversion + "\n" + "MMGeeks Dictionary Bot is based on dictionary database from Mysteryzillion.\nFor more information, please visit http://www.mmgeeks.org/forum/viewtopic.php?f=91&t=916";


        }// end of if /dictversion
        
        if (commands[2].equals(command[0])) // if command is /total
        {
            message = "Total words in the dictionary - " + dictionary.size() + " and adding more..." + "\nTemp words - " + temp_dict.size();

        }// end of if /total

        if (commands[3].equals(command[0])) // if command is /add
        {
            if (command.length<4)
            {
                message = "Invalid Format.\n Correct format example is \n /add sun v ေန။ ေနမင္းႀကီး။";
            }// end if
            else
            {
                message = command[1] + "\t" + command[2] + "\t";
                for (int i=3; i<command.length; i++)
                {
                    message = message + " " + command[i];
                }// end for loop
                message += "\r\n";
                if (WriteToFile(tempFile, from[0] + "\t" + message))
                {
                    String[] token = message.split("\\t");

                    if (temp_dict.containsKey(token[0]))
                    {
                         temp_dict.put(token[0], temp_dict.get(token[0]) + " "  + "(" + token[1] + ")" + " " + token[2]);
                    }
                    else
                    {
                        temp_dict.put(token[0], "(" + token[1] + ")" + " " + token[2]);
                    }
                    System.out.println("Write to file completed.");
                    message = "Thanks you. Data is successfully written to file and waiting for approval.";
                }
                else
                {
                    message = "Error in writing file. Please try again later.";
                }// end write else
            }// end else

        }// end of if /add

        try{
            chat.sendMessage(message);
        } catch(XMPPException e) {
			e.printStackTrace();
		}
    }// end of doCommand function
/* ****************************************************************************/
	public static void main(String args[]) {
		GTalkDict bot = new GTalkDict("config.txt");
		System.out.println("Bot is running... ");
		while(true);
	}

}
